
/*
    Chemistry Formula Balancer

	作者：xkhhdx (xkhhdx [at] gmail [dot] com)
	时间：Aug.10th, 2009

	本程序是一个开源的自由软件，你可以在自由软件基金会的 GNU通用公共许可
	证协议 2.0 的许可下改写或修改本软件。

	修改之后请在你的声明信息中保留本段信息。

	请遵循 GNU GPL v2 协议的条款，具体细节请阅读此协议。

    本文件主要实现了 balancer::make_formula() 函数。
*/
#include "balancer.h"

#define max( x, y ) ( x > y ? x : y )
#define min( x, y ) ( x > y ? y : x )

#pragma warning (disable:4786)

void balancer::make_formula()
{
	std::list < chemistry_formula >::iterator iter;
	iter = reacts.begin();
	char t = 'a';

	for( ; iter != reacts.end(); iter++, t++ )
	{
		iter->m_symbol = t;
	}

	iter = outers.begin();
	for( ; iter != outers.end(); iter++, t++ )
	{
		iter->m_symbol = t;
	}

#define insert( letter, value ) m_coefficient_map.insert( map < char, int > :: value_type( letter, value ) )
	while( t-- )
	{
		insert( t, 0 );
		if( t == 'a' )
			break;
	}
#undef insert


#ifdef PROG_DEBUG

	map < string, int >::iterator mi;

	// 将列出的方程显示到屏幕上
	t = 0;
	for( mi = m_elements.begin(); mi != m_elements.end(); mi++ )
	{
		iter = reacts.begin();
		std::list < chemistry_formula >::iterator iter2 = outers.begin();
		cout << mi->first.c_str() << " : \t";
		for( ; iter != reacts.end(); iter++, t++ )
		{
			if( iter->m_element_mass_map.find( mi->first ) != iter->m_element_mass_map.end() )
				cout << ( ( t == 0 ) ? "" : " + " ) << iter->m_element_mass_map.find( mi->first )->second << " * " << iter->m_symbol.c_str();
			else
				cout << " + 0 * " << iter->m_symbol.c_str();
		}
		for( ; iter2 != outers.end(); iter2++, t++ )
		{
			if( iter2->m_element_mass_map.find( mi->first ) != iter2->m_element_mass_map.end() )
				cout << ( ( t == 0 ) ? "" : " - " ) << iter2->m_element_mass_map.find( mi->first )->second << " * " << iter2->m_symbol.c_str();
			else
				cout << " - 0 * " << iter2->m_symbol.c_str();


		}
		cout << " = 0" << endl;
		t = 0;
	}
#endif

	// 限制：矩阵大小：10×10，也就是最多 9 个反应物，最多 9 种元素
	// 可以修改 balancer.h 中的 matrix [10][10] 以及 matrix_degree 来修改这个限制

	int line_count = m_elements.size();

	int row_count = reacts.size() + outers.size();

	int matrix_degree = max( line_count, row_count );

	cout << " line_count = " << line_count << ", row_count" << row_count << endl;

	int i = 0, j = 0;

	for( i = 0; i <= 9; i++ )
		for( j = 0; j <= 9; j++ )
			matrix[i][j] = 0;

	// 生成矩阵
	int line = 0, row = 0;

	for( mi = m_elements.begin(); mi != m_elements.end(); mi++, line++ )
	{
		iter = reacts.begin();
		std::list < chemistry_formula >::iterator iter2 = outers.begin();
		for( ; iter != reacts.end(); iter++, row++ )
		{
			int offset = reacts.size();

			if( iter->m_element_mass_map.find( mi->first ) != iter->m_element_mass_map.end() )

			{
				int eleval = 0 + iter->m_element_mass_map.find( mi->first )->second;

				matrix[line][row] = eleval;
			}
			else
				matrix[line][row] = 0;
			//  matrix [line][row] = eleval; // iter -> m_element_mass_map.find( mi -> first ) -> second;
		}
		for( ; iter2 != outers.end(); iter2++, row++ )
		{
			int offset = reacts.size();

			if( iter2->m_element_mass_map.find( mi->first ) != iter2->m_element_mass_map.end() )
			{
				int eleval = 0 - iter2->m_element_mass_map.find( mi->first )->second;

				matrix[line][row] = eleval;
			}
			else
				matrix[line][row] = 0;
		}
		row = 0;
	}

	// 若不是方阵的情况，注意：未加验证！
	if( row_count > line_count )
	{
		for( i = line_count + 1; i <= 9; i++ )
			for( j = 0; j <= line_count; j++ )
				matrix[i][j] = 1;
	}

	i = line_count;
	matrix[i][i + 1] = 10;	//2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23; // 比较。。的方法 25 以下素数的乘积。
	for( j = 0; j <= line_count; j++ )
		matrix[i][j] = 1;

	this->matrix_degree = i + 1;	// 矩阵维数
#ifdef PROG_DEBUG
	// 显示矩阵
	cout << endl << endl << "matrix : " << endl;
	for( i = 0; i <= 8; i++ )
		for( j = 0; j <= 8; j++ )
			cout << matrix[i][j] << ( ( j == 8 ) ? "\n" : ( ( matrix[i][j] < 0 ) ? " " : "  " ) );
#endif
	cout << endl << endl;


}
